#pragma once

#include <optional>

#include <userver/congestion_control/controllers/linear_config.hpp>
#include <userver/congestion_control/controllers/v2.hpp>
#include <userver/congestion_control/limiter.hpp>
#include <userver/dynamic_config/source.hpp>
#include <userver/utils/periodic_task.hpp>
#include <userver/utils/sliding_interval.hpp>
#include <userver/yaml_config/yaml_config.hpp>

USERVER_NAMESPACE_BEGIN

namespace congestion_control::v2 {

class LinearController final : public Controller {
 public:
  using StaticConfig = Controller::Config;

  LinearController(
      const std::string& name, v2::Sensor& sensor, Limiter& limiter,
      Stats& stats, const StaticConfig& config,
      dynamic_config::Source config_source,
      std::function<v2::Config(const dynamic_config::Snapshot&)> config_getter);

  Limit Update(const Sensor::Data& current) override;

 private:
  StaticConfig config_;
  utils::SlidingInterval<int64_t> current_load_;
  utils::SlidingInterval<int64_t> long_timings_;
  utils::SlidingInterval<int64_t> short_timings_;
  std::optional<std::size_t> current_limit_;
  std::size_t epochs_passed_{0};

  dynamic_config::Source config_source_;
  std::function<v2::Config(const dynamic_config::Snapshot&)> config_getter_;
};

LinearController::StaticConfig Parse(
    const yaml_config::YamlConfig& value,
    formats::parse::To<LinearController::StaticConfig>);

}  // namespace congestion_control::v2

USERVER_NAMESPACE_END
